//读取AD值并转换成F温度值,得出 烤炉温度,肉探针1温度,肉探针2温度

#include "TempADC.h"

#define AD_default_value 0

unsigned int ADC_Value=0;
uint8_t value_error = 0;
uint8_t LowTemp_Ctrl = 0; //1:重置低温检测过程, 0:继续执行低温检测
uint16_t LowTemp_Step = 0;
uint16_t LowTemp_Count = 0;
uint16_t ADC_Sample_Count = 0; //20ms
uint16_t Alarm_Tick_1s;
uint16_t ADC_Tick_20ms; //ADC采样间隔2ms计数uint16_t ADC_Tick_20ms; //ADC采样间隔2ms计数
uint16_t AD_Tick_20mS_Count;
double temp_Double = 0;
_RTD RTD[RTD_Seq_End];


void IO_Ref_ON(void)
{
	MR88FX02_Gpio_Set(IO_Ref,0);
	MR88FX02_Gpio_Set(IO_Oven,1);
	MR88FX02_Gpio_Set(IO_Probe1,1);
	MR88FX02_Gpio_Set(IO_Probe2,1);                                                                          
	MR88FX02_Gpio_Set(IO_Probe3,1);
	MR88FX02_Gpio_Set(IO_Probe4,1);
}

void IO_Oven_ON(void)
{
	MR88FX02_Gpio_Set(IO_Ref,1);
	MR88FX02_Gpio_Set(IO_Oven,0);
	MR88FX02_Gpio_Set(IO_Probe1,1);
	MR88FX02_Gpio_Set(IO_Probe2,1);                                                                          
	MR88FX02_Gpio_Set(IO_Probe3,1);
	MR88FX02_Gpio_Set(IO_Probe4,1);
	
}

void IO_Probe1_ON(void)
{
	MR88FX02_Gpio_Set(IO_Ref,1);
	MR88FX02_Gpio_Set(IO_Oven,1);
	MR88FX02_Gpio_Set(IO_Probe1,0);
	MR88FX02_Gpio_Set(IO_Probe2,1);
	MR88FX02_Gpio_Set(IO_Probe3,1);
	MR88FX02_Gpio_Set(IO_Probe4,1);
}
	
void IO_Probe2_ON(void)
{
	MR88FX02_Gpio_Set(IO_Ref,1);
	MR88FX02_Gpio_Set(IO_Oven,1);
	MR88FX02_Gpio_Set(IO_Probe1,1);
	MR88FX02_Gpio_Set(IO_Probe2,0);
	MR88FX02_Gpio_Set(IO_Probe3,1);
	MR88FX02_Gpio_Set(IO_Probe4,1);
}
	
void IO_Probe3_ON(void)
{
	MR88FX02_Gpio_Set(IO_Ref,1);
	MR88FX02_Gpio_Set(IO_Oven,1);
	MR88FX02_Gpio_Set(IO_Probe1,1);
	MR88FX02_Gpio_Set(IO_Probe2,1);
	MR88FX02_Gpio_Set(IO_Probe3,0);
	MR88FX02_Gpio_Set(IO_Probe4,1);
}
	
void IO_Probe4_ON(void)
{
	MR88FX02_Gpio_Set(IO_Ref,1);
	MR88FX02_Gpio_Set(IO_Oven,1);
	MR88FX02_Gpio_Set(IO_Probe1,1);
	MR88FX02_Gpio_Set(IO_Probe2,1);
	MR88FX02_Gpio_Set(IO_Probe3,1);
	MR88FX02_Gpio_Set(IO_Probe4,0);
}


void ADInit(void)
{
	MR88FX02_Adc_Init(Adc_Table);
	IO_Mode_RTD();
	IO_Mode_Ref();
	IO_Mode_Oven();
	IO_Mode_Probe1();
	IO_Mode_Probe2();
	IO_Mode_Probe3();
	IO_Mode_Probe4();
	MR88FX02_Adc_Set_Convert_Channel(ADC_Channel_RTD);
	MR88FX02_Adc_Start_Convert();
	while(!MR88FX02_Adc_Check_Cmplt_Flag());
	MR88FX02_Adc_Clr_Cmplt_Flag();
	ADC_Value = MR88FX02_Adc_Get_Result(12);
	
	RTD[RTD_Seq_ProbePG].status = Pt_Normal;
}


// Q:过程噪声，Q增大，动态响应变快，收敛稳定性变坏
// R:测量噪声，R增大，动态响应变慢，收敛稳定性变好   
uint32_t Kalman_Filter(uint32_t last,uint32_t z_measure)
{
  static float x_last=0;   
	static float p_last=0.02 * 50; //0.02;
	float Q=0.018 * 10;
	float R=0.542 * 10;
	float kg;
	float x_mid;
	float x_now;
	float p_mid;
	float p_now;

	x_last= last;
	x_mid=x_last;
    
    x_mid = x_last;    //x_last=x(k-1|k-1),x_mid=x(k|k-1)
    p_mid = p_last+Q;  //p_mid=p(k|k-1),p_last=p(k-1|k-1),Q=噪声
    kg=p_mid/(p_mid+R); //kg为kalman filter，R为噪声
    
    x_now=x_mid+kg*(z_measure-x_mid);//估计出的最优值

    // printf("测量值: %d\n",z_measure);  //显示测量值以及真值与测量值之间的误差
    // printf("卡尔曼滤波值: %f\n\n",x_now);  //显示kalman估计值以及真值和卡尔曼估计值的误差

    p_now=(1-kg)*p_mid;//最优值对应的covariance
    p_last = p_now;  //更新covariance值
    x_last = x_now;  //更新系统状态值

    return (uint32_t)x_now;
}

//中位值平均滤波算法, 支持10个数据滤波
//Fiter(0,10): 能返回滤波结果
//除了滤波,采样的数据也不能是同一个点,否则滤波的数据都来自同一个点,滤波也就没意义
uint32_t Filter(uint32_t ch, uint32_t temp)
{
    static uint32_t data[RTD_Seq_End][10];
    static uint32_t dataSeq = 0;
    uint32_t i = 0;
    static uint32_t total[RTD_Seq_End],total_pre[RTD_Seq_End];
    uint32_t sum = 0;

    if(ch >= RTD_Seq_End) return 0;
    if(temp != 0xffffffff)
    {
        data[ch][dataSeq] = temp;
        if(dataSeq > 0)
        {
            for (i = dataSeq; i > 0; i--)
            {
                if(data[ch][i] < data[ch][i - 1])
                {
                    temp = data[ch][i - 1];
                    data[ch][i - 1] = data[ch][i];
                    data[ch][i] = temp;
                }
            }
        }
        if(dataSeq < 9) dataSeq++;
    }
    else
    {
        if(dataSeq > 0)
        {
            for (i = 0; i < dataSeq; i++)
            {
                sum += data[ch][i];
            }
            // sum = data[ch][4] + data[ch][5];
            // total[ch] = (sum / 2);
            total[ch] = (sum / dataSeq);
            dataSeq = 0;
        }
        if((total[ch] > (total_pre[ch] + 50)) || ((total[ch] + 50) < total_pre[ch])) total_pre[ch] = total[ch]; //超出绝对值范围,加快滤波
        for(i = 0; i < 10; i++)
        {
            total[ch] = Kalman_Filter(total_pre[ch],total[ch]);
            total_pre[ch] = total[ch];
        }
    }
    return total[ch];
}

//Tick 10ms
void ADC_Clock_10ms(void)
{
    static uint16_t count = 0;

    if(ADC_Tick_20ms < 0xffff) ADC_Tick_20ms++;
    if(Alarm_Tick_1s < 0xffff) Alarm_Tick_1s++;
    count++;
    if(count >= 2)
    {
        count = 0;
        AD_Tick_20mS_Count++;
    }
}

//高温报警: 烤炉温度长时间>550°F,Tick 1s
void HighTempAlarm(void)
{
    static uint16_t HighTemp_Count = 0;

    if (RTD[0].value >= 650)
    {
        if (HighTemp_Count >= 5)
        { //持续5s,执行高温报警
            RTD[0].status = Pt_HighTemp;
        }
        else HighTemp_Count++;
    }
    else HighTemp_Count = 0;
}

//低温报警功能: 烤炉温度长时间低于120°F
void LowTempAlarm(void)
{
//    if(lcd_show_config.ShowBit == 0)
//    {
//        LowTemp_Count = 0;
//        LowTemp_Step = 0;
//        LowTemp_Ctrl = 0;
//        return;
//    }

    if (Alarm_Tick_1s >= 100)
    { //Tick 1s
        Alarm_Tick_1s -= 100;

        if(LowTemp_Count < 0xfff0) LowTemp_Count++;
        if ((LowTemp_Count >= 240) && (LowTemp_Step == 0))
        { //开机上电后延迟 240s
            LowTemp_Count = 0;
            LowTemp_Step = 1;
        }
        else if(LowTemp_Step == 1)
        {
            if (RTD[0].value < 120)
            {
                if ((LowTemp_Count >= 600) && (LowTemp_Ctrl == 1))
                { //持续600s,执行低温报警
                    RTD[0].status = Pt_LowTemp;
                }
                else if((LowTemp_Count >= 600) && (LowTemp_Ctrl != 1))
                {
                    LowTemp_Count = 0;
                    LowTemp_Ctrl = 1;
                    LowTemp_Step = 0;
                }
            }
            else
            {
                LowTemp_Step = 1;
                LowTemp_Count = 0;
            }
        }
        HighTempAlarm();
    }
}


void TempADC_Main(void)
{
    static uint16_t seq = 0;
    uint32_t temp = 0;
    double temp_Double = 0;
    static uint8_t ch = 0;

    if(ADC_Sample_Count == 0)
    {
        ADC_Sample_Count = 1;

        if(ch == RTD_Seq_RTD) IO_Ref_ON();
        else if(ch == RTD_Seq_ProbePG) IO_Oven_ON();
        else if(ch == RTD_Seq_Probe1) IO_Probe1_ON();
        else if(ch == RTD_Seq_Probe2) IO_Probe2_ON();
        else if(ch == RTD_Seq_Probe3) IO_Probe3_ON();
				else if(ch == RTD_Seq_Probe4) IO_Probe4_ON();
        MR88FX02_Adc_Start_Convert();
    }
    else if(ADC_Sample_Count >= 4)
    {
        ADC_Sample_Count = 0;

        if (seq < 10)
        { //读取AD采样值
            if (MR88FX02_Adc_Check_Cmplt_Flag() != 0)
            {
                MR88FX02_Adc_Clr_Cmplt_Flag();

                temp = MR88FX02_Adc_Get_Result(12);
                Filter(ch,temp);
                seq++;
            }
        }
        else
        {
            temp = Filter(ch,0xffffffff);
            temp_Double = AD_Convert_R(temp);
            temp_Double = Quadratic(temp_Double);
						Temp_icon_state = 2;
					  temp_Double = CTemp_Convert_FTemp(temp_Double);

            if(Pt1000_State == Pt1000_Short) 
							RTD[ch].status = Pt_Short;
            else if(Pt1000_State == Pt1000_Open) 
							RTD[ch].status = Pt_Open;
            else
            {
                if(ch == RTD_Seq_RTD)
                {
                    if((RTD[ch].status != Pt_LowTemp) && (RTD[ch].status != Pt_HighTemp) && (RTD[ch].status != Pt_ErF) && (RTD[ch].status != Pt_ErA))
                    {
                        RTD[ch].status = Pt_Normal;
                    }
                }
                else RTD[ch].status = Pt_Normal;
            }
            if(temp_Double > 999) temp_Double = 999; //999 ℉
            RTD[ch].value = temp_Double;
            ch++;
            if (ch >= RTD_Seq_End) ch = RTD_Seq_RTD;
            seq = 0;

#if Filter_Temp
            UI_System.RTD.Actual = Get_TempVirtual(RTD[RTD_Seq_RTD].value);
#else
            
//            Temperature = RTD[RTD_Seq_RTD].value;
#endif
//    extern uint16_t Temperature;//温度
//extern uint16_t Temperature_P1;//P1温度
//extern uint16_t Temperature_P2;//P2温度
//extern uint16_t Temperature_P3;//P3温度
//extern uint16_t Temperature_P4;//P4温度
						Temperature = RTD[RTD_Seq_ProbePG].value;
            Temperature_P1 = RTD[RTD_Seq_Probe1].value;
            Temperature_P2 = RTD[RTD_Seq_Probe2].value;
            Temperature_P3 = RTD[RTD_Seq_Probe3].value;
            Temperature_P4 = RTD[RTD_Seq_Probe4].value;

            if(RTD[RTD_Seq_RTD].status != Pt_Normal) UI_System.RTD_Seq_RTD.Pt_Status = RTD[RTD_Seq_RTD].status;
            else UI_System.RTD_Seq_RTD.Pt_Status = Pt_Normal;

            if(RTD[RTD_Seq_Probe1].status == Pt_Open) UI_System.Probe1.Pt_Status = Pt_Open;
            else if(RTD[RTD_Seq_Probe1].status == Pt_Short) UI_System.Probe1.Pt_Status = Pt_Short;
            else UI_System.Probe1.Pt_Status = Pt_Normal;

            if(RTD[RTD_Seq_Probe2].status == Pt_Open) UI_System.Probe2.Pt_Status = Pt_Open;
            else if(RTD[RTD_Seq_Probe2].status == Pt_Short) UI_System.Probe2.Pt_Status = Pt_Short;
            else UI_System.Probe2.Pt_Status = Pt_Normal;

            if(RTD[RTD_Seq_Probe3].status == Pt_Open) UI_System.Probe3.Pt_Status = Pt_Open;
            else if(RTD[RTD_Seq_Probe3].status == Pt_Short) UI_System.Probe3.Pt_Status = Pt_Short;
            else UI_System.Probe3.Pt_Status = Pt_Normal;

            if(RTD[RTD_Seq_ProbePG].status == Pt_Open) UI_System.ProbePG.Pt_Status = Pt_Open;
            else if(RTD[RTD_Seq_ProbePG].status == Pt_Short) UI_System.ProbePG.Pt_Status = Pt_Short;
            else UI_System.ProbePG.Pt_Status = Pt_Normal;

        }
    }
}



//Tick 2ms
void ADC_Clock_2ms(void)
{
    if((ADC_Sample_Count > 0) && (ADC_Sample_Count < 0xffff)) ADC_Sample_Count++;
}















